/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2013        */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be        */
/* attached to the FatFs via a glue function rather than modifying it.   */
/* This is an example of glue functions to attach various exsisting      */
/* storage control module to the FatFs module with a defined API.        */
/*-----------------------------------------------------------------------*/

#include "diskio.h"		/* FatFs lower layer API */
#include "drivers.h"
#include <stdio.h>
//#include "usbdisk.h"	/* Example: USB drive control */
//#include "atadrive.h"	/* Example: ATA drive control */
//#include "sdcard.h"		/* Example: MMC/SDC contorl */

/* Definitions of physical drive number for each media */
//#define ATA		0
//#define MMC		1
//#define USB		2


/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */
/*-----------------------------------------------------------------------*/

DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber (0..) */
)
{
	//SPI_FLASH_Init();
	//printf("SD Init success\n");
	//printf("Fat init, return OK\n");
	switch (pdrv)
	{
		case 0:
			return RES_OK;
		case 1:
			//RAM_Disk_Init();
			return RES_OK;
		default:
			return RES_ERROR;
	}
	           //
}



/*-----------------------------------------------------------------------*/
/* Get Disk Status                                                       */
/*-----------------------------------------------------------------------*/

DSTATUS disk_status (
	BYTE pdrv		/* Physical drive nmuber (0..) */
)
{
	/*if(pdrv)
	{
		printf("Only support drv 0\n");
		return STA_NOINIT;
	}	*/
	//printf("disk_status, return OK\n");
	return RES_OK;
}



/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
/*-----------------------------------------------------------------------*/

DRESULT disk_read (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE *buff,		/* Data buffer to store read data */
	DWORD sector,	/* Sector address (LBA) */
	BYTE count		/* Number of sectors to read (1..128) */
)
{
	int i;
	

	/*f (!count)
	{    
			return RES_PARERR;  //
	}*/
	//printf("rd disk %d at %d\n",pdrv,sector);
	switch (pdrv)
	{
		case 0:
			//sFlash
			for (i = 0; i < count; i++) 
			{
				SPI_FLASH_BufferRead((u8*) buff + i * 4096, (sector + i) * 4096, 4096);
			}
			return RES_OK;
		/*case 1:
			//RAM Disk
			for(i = 0; i < count; i++)
			{
				RAM_Disk_SectorRead((u8*) buff + i * 512 , (sector + i) * 512 , 1);
			}
			return RES_OK;*/
		default:
			return RES_PARERR;
	}
	//return RES_OK;
}



/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */
/*-----------------------------------------------------------------------*/

//#if _USE_WRITE
DRESULT disk_write (
	BYTE pdrv,			/* Physical drive nmuber (0..) */
	const BYTE *buff,	/* Data to be written */
	DWORD sector,		/* Sector address (LBA) */
	BYTE count			/* Number of sectors to write (1..128) */
)
{
	int i;
	
	/*if (!count)
	{    
			return RES_PARERR;  //only support device 0
	}*/
	//printf("wr disk %d at %d\n",pdrv,sector);
	switch (pdrv)
	{
		case 0:
			//sFlash
			for (i = 0; i < count; i++) 
			{
				SPI_FLASH_SectorErase((sector + i) * 4096);
				SPI_FLASH_BufferWrite((u8*) buff + i * 4096, (sector + i) * 4096, 4096);
			}
			return RES_OK;
		/*case 1:
			//RAM Disk
			for(i = 0; i < count; i++)
			{
				RAM_Disk_SectorWrite((u8*) buff + i * 512 , (sector + i) * 512 , 1);
			}
			return RES_OK;*/
		default:
			return RES_PARERR;
	}
	//return RES_OK;
}
//#endif


/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */
/*-----------------------------------------------------------------------*/

#if _USE_IOCTL
DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
	//printf("Get Disk %d ioctl %d\n",pdrv,cmd);
	switch (pdrv)
	{
		case 0:
			//sFlash
			switch (cmd)
			{
				case GET_SECTOR_SIZE:
					//printf("get GET_SECTOR_SIZE\n");
					*(unsigned long int*)buff = 4096;
					break;
				case GET_SECTOR_COUNT:
					//printf("get GET_SECTOR_COUNT\n");
					*(unsigned long int*)buff = 2048;
					break;
				/*default:
					return RES_ERROR;*/
			}
			return RES_OK;
		
		/*case 1:
			//RAM DISK
			switch (cmd)
			{
				case GET_SECTOR_SIZE:
					//printf("get GET_SECTOR_SIZE\n");
					*(unsigned long int*)buff = 512;
					break;
				case GET_SECTOR_COUNT:
					//printf("get GET_SECTOR_COUNT\n");
					*(unsigned long int*)buff = 16;
					break;
				case GET_BLOCK_SIZE:
					*(unsigned long int*)buff = 1;
					break;
				default:
					return RES_PARERR;
			}
			return RES_OK;*/
			
		default:
			return RES_PARERR;
	}
	//return RES_OK;
}
#endif

unsigned long int get_fattime(void)
{
	return 0;
}
